package org.ehe.erp.service.product.impl;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.extern.slf4j.Slf4j;
import org.ehe.business.workstation.domain.Workstation;
import org.ehe.business.workstation.service.IWorkstationService;
import org.ehe.business.workstation.service.WorkstationCodeService;
import org.ehe.common.core.enums.CommonStatusEnum;
import org.ehe.common.core.exception.BusinessException;
import org.ehe.common.core.exception.ServiceException;
import org.ehe.common.core.utils.MapstructUtils;
import org.ehe.common.core.utils.StringUtils;
import org.ehe.common.core.utils.object.BeanUtils;
import org.ehe.common.mybatis.core.page.PageQuery;
import org.ehe.common.mybatis.core.page.TableDataInfo;
import org.ehe.common.satoken.utils.LoginHelper;
import org.ehe.erp.domain.product.ErpMaterial;
import org.ehe.erp.domain.product.ErpProduct;
import org.ehe.erp.domain.product.bo.ErpProductBo;
import org.ehe.erp.domain.product.bo.ErpProductQueryBo;
import org.ehe.erp.domain.product.vo.ErpProductCategoryVo;
import org.ehe.erp.domain.product.vo.ErpProductUnitVo;
import org.ehe.erp.domain.product.vo.ErpProductVo;
import org.ehe.erp.mapper.product.ErpProductMapper;
import org.ehe.erp.service.product.IErpProductCategoryService;
import org.ehe.erp.service.product.IErpProductService;
import org.ehe.erp.service.product.IErpProductUnitService;
import jakarta.annotation.Resource;
import lombok.RequiredArgsConstructor;
import org.ehe.erp.service.product.MaterialService;
import org.springframework.stereotype.Service;

import java.util.*;

import static org.ehe.common.core.utils.collection.CollectionUtils.convertMap;

/**
 * 产品信息Service业务层处理
 *
 * @author zhangnn
 * @date 2025-08-12
 */
@Slf4j
@RequiredArgsConstructor
@Service
public class ErpProductServiceImpl extends ServiceImpl<ErpProductMapper, ErpProduct> implements IErpProductService {

    @Resource
    private final ErpProductMapper baseMapper;
    @Resource
    private IErpProductCategoryService erpProductCategoryService;
    @Resource
    private IErpProductUnitService erpProductUnitService;
    @Resource
    private MaterialService materialService;
    @Resource
    private IWorkstationService workstationService;

    @Resource
    private WorkstationCodeService codeService;

    /**
     * 非标件
     */
    private static final String NON_STANDARD_CATEGORY = "03";


    /**
     * 查询产品信息列表
     */
    @Override
    public TableDataInfo<ErpProductVo> queryPageList(ErpProductBo bo, PageQuery pageQuery) {
        LambdaQueryWrapper<ErpProduct> lqw = buildQueryWrapper(bo);
        Page<ErpProductVo> result = baseMapper.selectVoPage(pageQuery.build(), lqw);
        List<ErpProductVo> records = buildProductVOList(result.getRecords());
        result.setRecords(records);
        return TableDataInfo.build(result);
    }

    /**
     * 查询产品信息列表
     */
    @Override
    public List<ErpProductVo> queryList(ErpProductBo bo) {
        LambdaQueryWrapper<ErpProduct> lqw = buildQueryWrapper(bo);
        return baseMapper.selectVoList(lqw);
    }

    private LambdaQueryWrapper<ErpProduct> buildQueryWrapper(ErpProductBo bo) {
        Map<String, Object> params = bo.getParams();
        LambdaQueryWrapper<ErpProduct> lqw = Wrappers.lambdaQuery();
        lqw.eq(null != bo.getId(), ErpProduct::getId, bo.getId());
        lqw.like(StringUtils.isNotBlank(bo.getName()), ErpProduct::getName, bo.getName());
        lqw.eq(StringUtils.isNotBlank(bo.getBarCode()), ErpProduct::getBarCode, bo.getBarCode());
        lqw.like(bo.getCategoryCode() != null, ErpProduct::getCategoryCode, bo.getCategoryCode());
        lqw.eq(bo.getUnitId() != null, ErpProduct::getUnitId, bo.getUnitId());
        lqw.eq(bo.getStatus() != null, ErpProduct::getStatus, bo.getStatus());
        return lqw;
    }

    /**
     * 查询产品信息
     */
    @Override
    public ErpProductVo queryById(Long id) {
        ErpProductVo vo = baseMapper.selectVoById(id);
        if (Objects.nonNull(vo)) {
            ErpProductCategoryVo categoryVo = erpProductCategoryService.selectByCode(vo.getCategoryCode());
            if (Objects.nonNull(categoryVo)) {
                vo.setCategoryId(categoryVo.getId());
                vo.setCategoryName(categoryVo.getName());
                vo.setCategoryCode(categoryVo.getFullCode());
            }
        }
        //非标件
        String code = vo.getCategoryCode();
        if(StringUtils.isNotBlank(vo.getType()) && vo.getType().equals(NON_STANDARD_CATEGORY)){
            Workstation workstation = workstationService.selectByCode(vo.getWorkstationCode());
            if(Objects.nonNull(workstation)){
                vo.setWorkstationName(workstation.getName());
            }
            code = NON_STANDARD_CATEGORY;
        }


        ErpProductCategoryVo categoryVo = erpProductCategoryService.selectByCode(code);
        if (Objects.isNull(categoryVo)) {
            return vo;
        }
        vo.setCategoryId(categoryVo.getId());
        vo.setCategoryName(categoryVo.getName());
        List<Long> pIds = new ArrayList<>();
        Long currentId = categoryVo.getParentId();

        for (int i = 0; i < 5; i++) {
            // 避免空指针，先判断当前ID是否有效
            if (currentId == null) {
                break;
            }
            ErpProductCategoryVo parentCategory = erpProductCategoryService.queryById(currentId);
            // 若父分类不存在或已到达顶级（parentId=0），则终止循环
            if (parentCategory == null || parentCategory.getParentId() == 0) {
                // 可根据需求决定是否添加顶级分类自身ID
                pIds.add(currentId);
                break;
            }
            // 添加当前父分类ID
            pIds.add(currentId);
            // 继续向上追溯父级
            currentId = parentCategory.getParentId();
        }

        // 按需求进行倒序
        Collections.reverse(pIds);
        vo.setParentIds(pIds);
        return vo;
    }

    /**
     * 新增产品信息
     */
    @Override
    public Boolean insertByBo(ErpProductBo bo) {
        if(null != bo.getId()){
            this.updateByBo(bo);
            return true;
        }

        ErpProduct add = MapstructUtils.convert(bo, ErpProduct.class);
        validEntityBeforeSave(add);
        add.setType(add.getCategoryCode().substring(0,2));
        if(StringUtils.isBlank(bo.getCustomizeCode())){
            add.setCustomizeCode(bo.getStandard());
        }
        // generateNum(add);
        boolean flag = baseMapper.insert(add) > 0;
        if (flag) {
            bo.setId(add.getId());
        }
        return flag;
    }

    /**
     * 修改产品信息
     */
    @Override
    public Boolean updateByBo(ErpProductBo bo) {
        ErpProduct update = MapstructUtils.convert(bo, ErpProduct.class);
        validEntityBeforeSave(update);
        if(StringUtils.isBlank(bo.getType()) && StringUtils.isNotBlank(bo.getCategoryCode())){
            update.setType(bo.getCategoryCode().substring(0,2));
        }
        //generateNum(update);
        return baseMapper.updateById(update) > 0;
    }

    /**
     * 自动生成流水号
     *
     * @param add
     */
    private void generateNum(ErpProduct add) {
        if (StringUtils.isBlank(add.getCustomizeCode())) {
            // 自动生成流水号
            ErpProductCategoryVo category = erpProductCategoryService.selectByCode(add.getCategoryCode());
            if (category == null) {
                throw new BusinessException("产品分类不存在，无法生成流水号");
            }
            String categoryCode = category.getCode();
            if (StringUtils.isBlank(categoryCode)) {
                throw new BusinessException("产品分类编码为空，无法生成流水号");
            }

            // 2. 查询该分类下最大的流水号
            LambdaQueryWrapper<ErpProduct> queryWrapper = Wrappers.lambdaQuery();
            queryWrapper.eq(ErpProduct::getCategoryCode, add.getCategoryCode())
                    .select(ErpProduct::getCustomizeCode)
                    .orderByDesc(ErpProduct::getCustomizeCode)
                    .last("LIMIT 1");

            ErpProduct lastProduct = baseMapper.selectOne(queryWrapper);

            int sequence = 1;
            if (lastProduct != null && StringUtils.isNotBlank(lastProduct.getCustomizeCode())) {
                String lastCode = lastProduct.getCustomizeCode();
                try {
                    // 截取序号部分（去除分类编码前缀）并加1
                    String sequenceStr = lastCode.substring(categoryCode.length());
                    sequence = Integer.parseInt(sequenceStr) + 1;
                } catch (NumberFormatException | StringIndexOutOfBoundsException e) {
                    // 序号格式异常或长度不匹配时从1开始
                    log.warn("解析流水号序号失败，使用默认序号1，流水号:{}", lastCode, e);
                }
            }

            // 3. 拼接完整流水号（序号补0至4位）
            String customizeCode = String.format("%04d", sequence);
            add.setCustomizeCode(customizeCode);
        }
    }

    /**
     * 保存前的数据校验
     */
    private void validEntityBeforeSave(ErpProduct entity) {
        ErpProduct existProject = this.baseMapper.selectOne(new LambdaQueryWrapper<ErpProduct>()
                .eq(ErpProduct::getCategoryCode, entity.getCategoryCode())
                .eq(ErpProduct::getCustomizeCode, entity.getCustomizeCode()));
        // 修改的场合下
        if (null != entity.getId() && Objects.nonNull(existProject)) {
            if (!existProject.getCustomizeCode().equals(entity.getCustomizeCode())) {
                // 看下新修改的流水号是否已经存在
                long count = this.baseMapper.selectCount(new LambdaQueryWrapper<ErpProduct>()
                        .eq(ErpProduct::getCategoryCode, entity.getCategoryCode())
                        .eq(ErpProduct::getCustomizeCode, entity.getCustomizeCode()));
                if (count > 0) {
                    throw new BusinessException("物料流水号[" + entity.getCustomizeCode() + "]已经存在");
                }
            }
            String processedName = entity.getName().replaceAll("[\\s　]+", "").trim();
            if (!existProject.getName().equals(processedName)) {
                checkCategoryName(entity);
            }
        } else {
            if (Objects.nonNull(existProject)) {
                throw new BusinessException(
                        "物料编码[" + existProject.getCategoryCode() + "." + existProject.getCustomizeCode() + "]已经存在");
            }
            checkCategoryName(entity);
        }
    }

    private void checkCategoryName(ErpProduct entity) {
        // 去除所有空格（包括全角、半角空格）
        String processedName = entity.getName().replaceAll("[\\s　]+", "").trim();

        // 数据库查询时同样处理：去除所有空格后比较
        ErpProduct product = this.baseMapper.selectOne(new LambdaQueryWrapper<ErpProduct>()
                // 同时处理半角和全角空格
                .apply("REPLACE(REPLACE(name, ' ', ''), '　', '') = {0}", processedName)
                // 增加必要的业务过滤条件
                .eq(ErpProduct::getTenantId, LoginHelper.getTenantId())
                .eq(ErpProduct::getDelFlag, 0));
        //非标件
        if (entity.getCategoryCode().equals(NON_STANDARD_CATEGORY)){
            entity.setType(NON_STANDARD_CATEGORY);

            WorkstationCodeService.CodeGenerateResult codeResult = codeService.generateCode(entity.getWorkstationCode(), "");
            entity.setCategoryCode(codeResult.getFullCode());
        }

        if (Objects.nonNull(product)) {
            if (product.getId().longValue() != entity.getId().longValue()) {
                throw new BusinessException("物料名称[" + entity.getName() + "]已经存在");

            }
        }
    }

    /**
     * 批量删除产品信息
     */
    @Override
    public Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid) {
        if (isValid) {
            // TODO 做一些业务上的校验,判断是否需要校验
        }
        return baseMapper.deleteBatchIds(ids) > 0;
    }

    /**
     * 查询产品精简列表
     */
    @Override
    public List<ErpProductVo> getProductListByStatus() {
        List<ErpProductVo> list = baseMapper.selectVoList(new LambdaQueryWrapper<ErpProduct>()
                .eq(ErpProduct::getStatus, CommonStatusEnum.ENABLE.getStatus()));
        return buildProductVOList(list);
    }

    @Override
    public List<ErpProductVo> validProductList(Collection<Long> ids) {
        if (CollUtil.isEmpty(ids)) {
            return Collections.emptyList();
        }
        List<ErpProductVo> list = baseMapper.selectVoBatchIds(ids);
        Map<Long, ErpProductVo> productMap = convertMap(list, ErpProductVo::getId);
        for (Long id : ids) {
            ErpProductVo product = productMap.get(id);
            if (productMap.get(id) == null) {
                // todo 异常信息封装处理
                throw new ServiceException("产品信息不存在");
            }
            if (CommonStatusEnum.isDisable(product.getStatus())) {
                // todo 异常信息封装处理
                throw new ServiceException("供应商({" + product.getName() + "})未启用");
            }
        }
        return list;
    }

    /**
     * 构建ErpProductVo，补全fullCode和fullName
     */
    @Override
    public ErpProductVo buildProductVO(ErpProductVo productVo) {
        if (productVo == null) {
            return new ErpProductVo();
        }

        // 设置单位名称
        if (productVo.getUnitId() != null) {
            ErpProductUnitVo unit = erpProductUnitService.queryById(productVo.getUnitId());
            if (unit != null) {
                productVo.setUnitName(unit.getName());
            }
        }

        // 设置材料名称
        ErpMaterial material = null;
        if (StringUtils.isNotBlank(productVo.getMaterial())) {
            material = materialService.getOne(new LambdaQueryWrapper<ErpMaterial>()
                    .eq(ErpMaterial::getMaterialCode, productVo.getMaterial()));
            if (material != null) {
                productVo.setMaterialName(material.getMaterialName());
            }
        }

        // 获取分类信息
        ErpProductCategoryVo category = null;
        if (StringUtils.isNotBlank(productVo.getCategoryCode())) {
            category = erpProductCategoryService.selectByCode(productVo.getCategoryCode());
            if (category != null) {
                productVo.setCategoryId(category.getId());
                productVo.setCategoryName(category.getFullName());
            }
        }

        // 非标件处理
        if (NON_STANDARD_CATEGORY.equals(productVo.getType())) {
            productVo.setFullCode(productVo.getCategoryCode());
            if (StringUtils.isNotBlank(productVo.getWorkstationCode())) {
                Workstation workstation = workstationService.selectByCode(productVo.getWorkstationCode());
                if (workstation != null) {
                    productVo.setFullName("非标准件_" + workstation.getName() + "_" + productVo.getName());
                }
            }
        } else {
            // 标准件/外购件等其他类型
            // 构建fullCode
            if (StringUtils.isNotBlank(productVo.getMaterial())) {
                productVo.setFullCode(productVo.getCategoryCode() + "." + productVo.getMaterial() + "."
                        + productVo.getCustomizeCode());
            } else {
                productVo.setFullCode(productVo.getCategoryCode() + "." + productVo.getCustomizeCode());
            }

            // 构建fullName
            StringBuilder fullName = new StringBuilder();
            if (category != null) {
                fullName.append(category.getFullName());
            }
            if (material != null && StringUtils.isNotBlank(material.getMaterialName())) {
                fullName.append("_").append(material.getMaterialName());
            }
            if (StringUtils.isNotBlank(productVo.getName())) {
                fullName.append("_").append(productVo.getName());
            }
            productVo.setFullName(fullName.toString());
        }

        return productVo;
    }

    /**
     * 重组返回结果
     *
     * @param list
     * @return
     */
    private List<ErpProductVo> buildProductVOList(List<ErpProductVo> list) {
        if (CollUtil.isEmpty(list)) {
            return Collections.emptyList();
        }
        // 批量获取所有需要的 categoryId 和 unitId
        Set<String> categoryCodes = new HashSet<>();
        Set<Long> unitIds = new HashSet<>();

        // 一次遍历获取所有的 categoryId 和 unitId
        for (ErpProductVo product : list) {
            categoryCodes.add(product.getCategoryCode());
            unitIds.add(product.getUnitId());
        }

        // 批量获取 categoryMap 和 unitMap
        Map<String, ErpProductCategoryVo> categoryMap = erpProductCategoryService.getProductCategoryMap(categoryCodes);
        Map<Long, ErpProductUnitVo> unitMap = erpProductUnitService.getProductUnitMap(unitIds);

        // 使用 BeanUtils.toBean 进行批量属性设置，避免重复查找
        return BeanUtils.toBean(list, ErpProductVo.class, product -> {
            // 设置分类名称
            ErpProductCategoryVo category = categoryMap.get(product.getCategoryCode());
            if (category != null) {
                product.setCategoryId(category.getId());
                product.setCategoryCode(category.getFullCode());
                product.setCategoryName(category.getFullName());
                if (product.getCategoryName().indexOf("_") > 0) {
                    List<String> ll = Arrays.asList(product.getCategoryName().split("_"));
                    product.setType(ll.get(0));
                }
            }

            // 设置单位名称
            ErpProductUnitVo unit = unitMap.get(product.getUnitId());
            if (unit != null) {
                product.setUnitName(unit.getName());
            }
            // 材料类型名称
            ErpMaterial material = materialService.getOne(new LambdaQueryWrapper<ErpMaterial>()
                    .eq(ErpMaterial::getMaterialCode, product.getMaterial()));
            if (Objects.nonNull(material)) {
                product.setMaterialName(material.getMaterialName());
            }
            if(StringUtils.isBlank(product.getType())){
                if(product.getCategoryCode().indexOf(".") > -1){
                    product.setType(Arrays.asList(product.getCategoryCode().split(".")).get(0));
                }
            }

            // 非标件
            if (StringUtils.isNotBlank(product.getType()) && product.getType().equals(NON_STANDARD_CATEGORY)) {
                product.setFullCode(product.getCategoryCode());
                Workstation workstation = workstationService.selectByCode(product.getWorkstationCode());
                if (Objects.nonNull(workstation)) {
                    product.setFullName("非标准件_" + workstation.getName() + "_" + product.getName());
                }
            } else {
                // 全码
                if (StringUtils.isNotBlank(product.getMaterial())) {
                    product.setFullCode(
                            product.getCategoryCode() + "." + product.getMaterial() + "." + product.getCustomizeCode());
                } else {
                    product.setFullCode(product.getCategoryCode() + "." + product.getCustomizeCode());
                }
                if (StringUtils.isNotBlank(product.getMaterialName())) {
                    product.setFullName(
                            product.getCategoryName() + "_" + material.getMaterialName() + "_" + product.getName());
                } else {
                    product.setFullName(product.getCategoryName() + "_" + product.getName());
                }
            }

        });
    }

    /**
     * 根据keys匹配物料信息
     * @param bo
     * @return
     */
    @Override
    public List<ErpProductVo> selectInfoByKeys(ErpProductQueryBo bo) {
        return this.baseMapper.selectVoList(new LambdaQueryWrapper<ErpProduct>()
            .eq(ErpProduct::getCategoryCode,bo.getCategoryCode())
            .like(ErpProduct::getName,bo.getName()));
    }
}
